﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 商品评价接口实现
    /// </summary>
    public class OrderEvaluateService : BaseService, IOrderEvaluateService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public OrderEvaluateService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<OrderEvaluate?> QueryAsync(Expression<Func<OrderEvaluate, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = await _context.Set<OrderEvaluate>()
                .Include(x => x.OrderGoods).ThenInclude(x => x!.Order)
                .Include(x => x.EvaluateAlbums)
                .Include(x => x.User).ThenInclude(x => x!.Member)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询指定数量总数
        /// </summary>
        public async Task<int> QueryCountAsync(Expression<Func<OrderEvaluate, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            return await _context.Set<OrderEvaluate>() .Include(x => x.EvaluateAlbums).Where(funcWhere).CountAsync();
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<OrderEvaluate>> QueryListAsync(int top, Expression<Func<OrderEvaluate, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<OrderEvaluate>()
                .Include(x => x.OrderGoods).ThenInclude(x => x!.Order)
                .Include(x => x.EvaluateAlbums)
                .Include(x => x.User).ThenInclude(x => x!.Member)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<OrderEvaluate>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<OrderEvaluate, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<OrderEvaluate>()
                .Include(x => x.OrderGoods).ThenInclude(x => x!.Order)
                .Include(x => x.EvaluateAlbums)
                .Include(x => x.User).ThenInclude(x => x!.Member)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<OrderEvaluate>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 添加一条记录
        /// </summary>
        public async Task<bool> AddAsync(long orderId, ICollection<OrderEvaluateEditDto> listDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查会员是否登录
            var userId = await _userService.GetUserIdAsync();
            if (listDto == null || listDto.Count == 0)
            {
                throw new ResponseException("找不到评价的商品");
            }
            //检查订单商品是否存在
            var orderModel = await _context.Set<Orders>().Include(x => x.OrderGoods).FirstOrDefaultAsync(x => x.Id == orderId && x.UserId == userId);
            if (orderModel == null)
            {
                throw new ResponseException("订单不存在或已删除", ErrorCode.NotFound, StatusCodes.Status404NotFound);
            }
            //循环写入
            var shopGoodsList = new List<ShopGoods>(); //待修改的商品列表
            var orderGoodsList = new List<OrderGoods>(); //待修改的订单商品列表
            var evaluateList = new List<OrderEvaluate>(); //待添加的评价列表
            foreach (var modelt in listDto)
            {
                //查找对应的订单商品
                var orderGoodsModel = orderModel.OrderGoods.FirstOrDefault(x => x.Id == modelt.OrderGoodsId);
                if (orderGoodsModel == null)
                {
                    throw new ResponseException("订单商品不存在或已删除");
                }
                if (orderGoodsModel.EvaluateStatus > 0)
                {
                    throw new ResponseException("订单商品已评价");
                }
                orderGoodsModel.EvaluateStatus = 1;//更改为已评价
                orderGoodsList.Add(orderGoodsModel);
                //查找对应的商品
                var goodsModel = shopGoodsList.FirstOrDefault(x => x.Id == orderGoodsModel.GoodsId);
                if (goodsModel != null)
                {
                    goodsModel.EvaluateCount++;
                    if (goodsModel.Merchant != null)
                    {
                        goodsModel.Merchant.EvaluateCount++;
                    }
                }
                else
                {
                    goodsModel = await _context.Set<ShopGoods>().Include(x => x.Merchant).FirstOrDefaultAsync(x => x.Id == orderGoodsModel.GoodsId);
                    if (goodsModel != null)
                    {
                        goodsModel.EvaluateCount++;
                        if (goodsModel.Merchant != null)
                        {
                            goodsModel.Merchant.EvaluateCount++;
                        }
                        shopGoodsList.Add(goodsModel);
                    }
                }

                //映射成实体
                var model = _mapper.Map<OrderEvaluate>(modelt);
                model.UserId = userId;
                model.UserName = await _userService.GetUserNameAsync();
                model.MerchantId = orderModel.MerchantId;
                model.AddTime = DateTime.Now;
                model.Status = 0;
                model.OrderId = orderId;
                evaluateList.Add(model);
            }
            //保存评价和修改订单商品评价状态
            _context.Set<ShopGoods>().UpdateRange(shopGoodsList);
            _context.Set<OrderGoods>().UpdateRange(orderGoodsList);
            await _context.Set<OrderEvaluate>().AddRangeAsync(evaluateList);
            var result = await this.SaveAsync();
            if (!result)
            {
                throw new ResponseException("数据保存时发生意外错误");
            }
            return result;
        }

        /// <summary>
        /// 修改一条记录
        /// </summary>
        public async Task<bool> UpdateAsync(long id, OrderEvaluateEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //根据ID获取记录
            var model = await _context.Set<OrderEvaluate>().Where(x => x.Id == id)
                .Include(x => x.EvaluateAlbums)
                .FirstOrDefaultAsync();
            //如果不存在则抛出异常
            if (model == null)
            {
                throw new ResponseException("数据不存在或已删除", ErrorCode.NotFound, StatusCodes.Status404NotFound);
            }
            //将DTO映射到源数据
            var mapModel = _mapper.Map(modelDto, model);
            //保存
            _context.Set<OrderEvaluate>().Update(mapModel);
            return await this.SaveAsync();
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<OrderEvaluate, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var list = await _context.Set<OrderEvaluate>()
                .Include(x => x.EvaluateAlbums).Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            foreach (var modelt in list)
            {
                _context.Set<OrderEvaluate>().Attach(modelt);
            }
            _context.Set<OrderEvaluate>().RemoveRange(list);
            return await this.SaveAsync();
        }
    }
}
